<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.11"/>
<title>libwebsockets: Notes about generic-table</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
  $(window).load(resizeHeight);
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="libwebsockets.org-logo.png"/></td>
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">libwebsockets
   </div>
   <div id="projectbrief">Lightweight C library for HTML5 websockets</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.11 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li class="current"><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('md_README.generic-table.html','');});
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<div class="title">Notes about generic-table </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="gtint"></a>
What is generic-table?</h1>
<p>Generic-table is a JSON schema and client-side JS file that makes it easy to display live, table structured HTML over a ws link.</p>
<p>An example plugin and index.html using it are provided, but lwsgt itself doesn't have its own plugin, it's just a JSON schema and client-side JS that other plugins can use to simplify displaying live, table-based data without having to reinvent the wheel each time.</p>
<p>The ws protocol sends JSON describing the table, and then JSON updating the table contents when it chooses, the brower table is updated automatically, live.</p>
<div class="image">
<img src="lwsgt-overview.png" alt="lwsgt-overview.png"/>
</div>
<ul>
<li>Example protocol plugin (displays directory contents): <a href="https://github.com/warmcat/libwebsockets/tree/master/plugins/generic-table/protocol_table_dirlisting.c">https://github.com/warmcat/libwebsockets/tree/master/plugins/generic-table/protocol_table_dirlisting.c</a></li>
<li>Example HTML: <a href="https://github.com/warmcat/libwebsockets/tree/master/plugins/generic-table/assets/index.html">https://github.com/warmcat/libwebsockets/tree/master/plugins/generic-table/assets/index.html</a></li>
<li>lwsgt.js (client-side table rendering / ws link management): <a href="https://github.com/warmcat/libwebsockets/tree/master/plugins/generic-table/assets/lwsgt.js">https://github.com/warmcat/libwebsockets/tree/master/plugins/generic-table/assets/lwsgt.js</a></li>
</ul>
<h1><a class="anchor" id="gteb"></a>
Enabling for build</h1>
<p>Enable the demo plugin at CMake with -DLWS_WITH_PLUGINS=1</p>
<h1><a class="anchor" id="gtinth"></a>
Integrating with your html</h1>
<ul>
<li>In your HEAD section, include lwsgt.js</li>
</ul>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;script src=&quot;lwsgt.js&quot;&gt;&lt;/script&gt;</div></div><!-- fragment --><ul>
<li>Also in your HEAD section, style the lwsgt CSS, eg</li>
</ul>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;style&gt;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;.lwsgt_title { font-size: 24; text-align:center }</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;.lwsgt_breadcrumbs { font-size: 18; text-align:left }</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;.lwsgt_table { font-size: 14; padding:12px; margin: 12px; align:center }</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;.lwsgt_hdr { font-size: 18; text-align:center;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;             background-color: rgba(40, 40, 40, 0.8); color: white }</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;.lwsgt_tr { padding: 10px  }</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;.lwsgt_td { padding: 3px  }</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;&lt;/style&gt;</div></div><!-- fragment --><p>You can skip this but the result will be less beautiful until some CSS is provided.</p>
<ul>
<li>In your body section, declare a div with an id (can be whatever you want)</li>
</ul>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;tr&gt;&lt;td&gt;&lt;div id=&quot;lwsgt1&quot; class=&quot;group1&quot;&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;</div></div><!-- fragment --><p>lwsgt JS will put its content there.</p>
<ul>
<li>Finally in a &lt;script&gt; at the end of your page, instantiate lwsgt and provide a custom callback for clickable links</li>
</ul>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;script&gt;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;var v1 = new lwsgt_initial(&quot;Dir listing demo&quot;,</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;                           &quot;protocol-lws-table-dirlisting&quot;,</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;                           &quot;lwsgt1&quot;, &quot;lwsgt_dir_click&quot;, &quot;v1&quot;);</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;function lwsgt_dir_click(gt, u, col, row)</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;{</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;        if (u[0] == &#39;=&#39;) { /* change directory */</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;                window[gt].lwsgt_ws.send(u.substring(1, u.length));</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;                return;</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;        }</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;        var win = window.open(u, &#39;_blank&#39;);</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;        win.focus();</div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;}</div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;</div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;&lt;/script&gt;</div></div><!-- fragment --><p>In the callback, you can recover the ws object by <code>window[gt].lwsgt_ws</code>.</p>
<h1><a class="anchor" id="gtc"></a>
Lwsgt constructor</h1>
<p>To instantiate the ws link and lwsgt instance, your HTML must call a lwsgt constructor for each region on the page managed by lwsgt.</p>
<p><code>var myvar = new lwsgt_initial(title, ws_protocol, div_id, click_cb, myvar);</code></p>
<p>All of the arguments are strings.</p>
<table class="doxtable">
<tr>
<th>Parameter </th><th>Description  </th></tr>
<tr>
<td>title </td><td>Title string to go above the table </td></tr>
<tr>
<td>ws_protocol </td><td>Protocol name string to use when making ws connection </td></tr>
<tr>
<td>div_id </td><td>HTML id of div to fill with content </td></tr>
<tr>
<td>click_cb </td><td>Callback function name string to handle clickable links </td></tr>
<tr>
<td>myvar </td><td>Name of var used to hold this instantiation globally </td></tr>
</table>
<p>Note "myvar" is needed so it can be passed to the click handling callback.</p>
<h1><a class="anchor" id="gtclick"></a>
Lwsgt click handling function</h1>
<p>When a clickable link produced by lwsgt is clicked, the function named in the click_cb parameter to lwsgt_initial is called.</p>
<p>That function is expected to take four parameters, eg</p>
<p><code>function lwsgt_dir_click(gt, u, col, row)</code></p>
<table class="doxtable">
<tr>
<th>Parameter </th><th>Description  </th></tr>
<tr>
<td>gt </td><td>Name of global var holding this lwsgt context (ie, myvar) </td></tr>
<tr>
<td>u </td><td>Link "url" string </td></tr>
<tr>
<td>col </td><td>Table column number link is from </td></tr>
<tr>
<td>row </td><td>Table row number link is from </td></tr>
</table>
<h1><a class="anchor" id="gtgj"></a>
Generic-table JSON</h1>
<h3>Column layout</h3>
<p>When the ws connection is established, the protocol should send a JSON message describing the table columns. For example</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&quot;cols&quot;: [</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;      { &quot;name&quot;: &quot;Date&quot; },</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;      { &quot;name&quot;: &quot;Size&quot;, &quot;align&quot;: &quot;right&quot; },</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;      { &quot;name&quot;: &quot;Icon&quot; },</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;      { &quot;name&quot;: &quot;Name&quot;, &quot;href&quot;: &quot;uri&quot;},</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;      { &quot;name&quot;: &quot;uri&quot;, &quot;hide&quot;: &quot;1&quot; }</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;  ]</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;}</div></div><!-- fragment --><ul>
<li>This describes 5 columns</li>
<li>Only four columns (not "uri") should be visible</li>
<li>"Name" should be presented as a clickable link using "uri" as the destination, when a "uri" field is presented.</li>
<li>"Size" field should be presented aligned to the right</li>
</ul>
<h3>Breadcrumbs</h3>
<p>When a view is hierarchical, it's useful to provide a "path" with links back in the "path", known as "breadcrumbs".</p>
<p>Elements before the last one should provide a "url" member as well as the displayable name, which is used to create the link destination.</p>
<p>The last element, being the current displayed page should not have a url member and be displayed without link style.</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&quot;breadcrumbs&quot;:[{&quot;name&quot;:&quot;top&quot;, &quot;url&quot;: &quot;/&quot; }, {&quot;name&quot;:&quot;mydir&quot;}]</div></div><!-- fragment --><h3>Table data</h3>
<p>The actual file data consists of an array of rows, containing the columns mentioned in the original "cols" section.</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&quot;data&quot;:[</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;        {</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;         &quot;Icon&quot;:&quot; &quot;,</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;         &quot;Date&quot;:&quot;2015-Feb-06 03:08:35 +0000&quot;,</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;         &quot;Size&quot;:&quot;1406&quot;,</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;         &quot;uri&quot;:&quot;./serve//favicon.ico&quot;,</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;         &quot;Name&quot;:&quot;favicon.ico&quot;</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;        }</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;]</div></div><!-- fragment --><h1><a class="anchor" id="gtdirl"></a>
Setting up protocol-lws-table-dirlisting</h1>
<p>The example protocol needs two mounts, one to provide the index.html, js and the protocol itself</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;{</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160; &quot;mountpoint&quot;: &quot;/dirtest&quot;,</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160; &quot;origin&quot;: &quot;file:///usr/share/libwebsockets-test-server/generic-table&quot;,</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160; &quot;origin&quot;: &quot;callback://protocol-lws-table-dirlisting&quot;,</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160; &quot;default&quot;: &quot;index.html&quot;,</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160; &quot;pmo&quot;: [{</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;        &quot;dir&quot;: &quot;/usr/share/libwebsockets-test-server&quot;</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160; }]</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;},</div></div><!-- fragment --><p>The protocol wants a per-mount option (PMO) to tell it the base directory it is serving from, named "dir".</p>
<p>The other mount is there to simply serve items that get clicked on from the table in a secure way</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;{</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160; &quot;mountpoint&quot;: &quot;/dirtest/serve&quot;,</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160; &quot;origin&quot;: &quot;file:///usr/share/libwebsockets-test-server&quot;,</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160; &quot;default&quot;: &quot;index.html&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;},</div></div><!-- fragment --><p>This last bit is not related to using lwsgt itself. </p>
</div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
  </ul>
</div>
</body>
</html>
